package com.example.ipcputest.util;


import com.example.ipcputest.bean.JvmRuntimeInfo;
import com.sun.management.OperatingSystemMXBean;

import java.lang.management.*;
import java.text.DecimalFormat;

/**
 * 获取jvm运行时信息
 * @author liuyang
 */
public class JvmInfoUtil {

    /** CPU时间 */
    private static double cpuTime;

    /** 当前系统时间（毫秒） */
    private static long collectTime;

    /** 堆内存使用大小记录 */
    private static long heapMemoryUsedMin;

    /** CPU个数 */
    private static final int PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();

    /**
     * 注：此处使用 use com.sun.management.OperatingSystemMXBean
     */
    private static final OperatingSystemMXBean OPERATING_SYSTEM_MX_BEAN = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

    private static final RuntimeMXBean RUNTIME_MX_BEAN = ManagementFactory.getRuntimeMXBean();

    private static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean();

    private static final ClassLoadingMXBean LOADING_MX_BEAN = ManagementFactory.getClassLoadingMXBean();

    private static final MemoryMXBean MEMORY_MX_BEAN = ManagementFactory.getMemoryMXBean();

    private static DecimalFormat df=new DecimalFormat("0.0000");

    private JvmInfoUtil() {
        cpuTime = getProcessCpuTime();
        collectTime = System.currentTimeMillis();
        heapMemoryUsedMin = 0;
    }

    /**
     * get process cpu in nanoseconds
     */
    private static double getProcessCpuTime() {
        return OPERATING_SYSTEM_MX_BEAN.getProcessCpuTime();
    }

    /**
     * 获取JVM_CPU使用率
     */
    private static double getCpuUsage() {
        double newCpuTime = getProcessCpuTime();
        long newCollectTime = System.currentTimeMillis();
        //1000_000 = 1000000 增强可读性
        //将cpuTime纳秒转换成毫秒/cpu个数
        double cpu = Double.parseDouble(df.format((newCpuTime - cpuTime) / (newCollectTime - collectTime) / 1000_000 / PROCESSOR_COUNT));
        cpuTime = newCpuTime;
        collectTime = newCollectTime;
        return cpu;
    }

    public static JvmRuntimeInfo getJvmInfo(){
        JvmRuntimeInfo jvmRunTimeInfo = new JvmRuntimeInfo();
        jvmRunTimeInfo.setCpuUsage(getCpuUsage());
        //获取程序运行时长
        jvmRunTimeInfo.setRunningTime(RUNTIME_MX_BEAN.getUptime());
        //活动线程总数
        jvmRunTimeInfo.setThreadCount(THREAD_MX_BEAN.getThreadCount());
        //峰值
        jvmRunTimeInfo.setPeakThreadCount(THREAD_MX_BEAN.getPeakThreadCount());
        //线程总数
        jvmRunTimeInfo.setTotalStartedThreadCount(THREAD_MX_BEAN.getTotalStartedThreadCount());
        //守护线程总数
        jvmRunTimeInfo.setDaemonThreadCount(THREAD_MX_BEAN.getDaemonThreadCount());
        //已加载当前类
        jvmRunTimeInfo.setLoadedClassCount(LOADING_MX_BEAN.getLoadedClassCount());
        //已加载类总数
        jvmRunTimeInfo.setTotalLoadedClassCount(LOADING_MX_BEAN.getTotalLoadedClassCount());
        //已卸载类总数
        jvmRunTimeInfo.setUnloadedClassCount(LOADING_MX_BEAN.getUnloadedClassCount());
        //堆使用量
        jvmRunTimeInfo.setHeapUsedMemory(MEMORY_MX_BEAN.getHeapMemoryUsage().getUsed());
        //最大堆使用量
        jvmRunTimeInfo.setHeapMaxMemory(MEMORY_MX_BEAN.getHeapMemoryUsage().getMax());
        //最小堆使用量
        heapMemoryUsedMin = jvmRunTimeInfo.getHeapUsedMemory()<heapMemoryUsedMin?jvmRunTimeInfo.getHeapUsedMemory():heapMemoryUsedMin;
        jvmRunTimeInfo.setHeapMinMemory(heapMemoryUsedMin);
        //堆提交的内存量
        jvmRunTimeInfo.setHeapCommittedMemory(MEMORY_MX_BEAN.getHeapMemoryUsage().getCommitted());
        return jvmRunTimeInfo;
    }


}
